package com.sailfish.springbootdemo.controller.db7;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sailfish.springbootdemo.configs.UserHeaderHolder;
import com.sailfish.springbootdemo.dao.db7.*;
import com.sailfish.springbootdemo.pojo.Result;
import com.sailfish.springbootdemo.pojo.db7.*;
import com.sailfish.springbootdemo.service.db2.S3UploadFileService;
import com.sailfish.springbootdemo.service.db7.CommonService;
import com.sailfish.springbootdemo.service.db7.TaskCenterService;
import com.sailfish.springbootdemo.service.db7.TbTemplateService;
import com.sailfish.springbootdemo.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

@RestController
@CrossOrigin
@RequestMapping("/TaskCenter")
public class TaskCenterController {

    @Value("${personal.config.apis.sign}")
    private String sign;

    @Value("${personal.config.apis.get-All-Board-Params-api}")
    private String getAllBoardParamsApi;

    @Value("${personal.config.apis.get-All-Board-ParamsBy0310AndVersion-api}")
    private String getAllBoardParamsBy0310AndVersionapi;



    @Value("${personal.config.file.file-save-url}")
    private String fileSaveUrl;
    @Value("${personal.config.env}")
    private String env;
    @Value("${personal.config.amazon-s3.url}")
    private String url;
    @Value("${personal.config.amazon-s3.file-bucket}")
    private String fileBucket;

    @Autowired
    SfsUtils sfsUtils;
    @Autowired
    S3UploadFileService s3UploadFileService;

    @Autowired
    private TbTemplateService tbTemplateService;

    @Autowired
    private TaskCenterService taskCenterService;

    @Autowired
    private TbFlowCompVplAttrDao tbFlowCompVplAttrDao;

    @Autowired
    private TbFlowCompVplPinAttrDao tbFlowCompVplPinAttrDao;

    @Autowired
    private TbFlowProcessDetailDao tbFlowProcessDetailDao;

    @Autowired
    private TbKnowledgeBaseFileDao tbKnowledgeBaseFileDao;

    @Autowired
    private TbFlowCompPkgDao tbFlowCompPkgDao;

    @Autowired
    private TruncateTableDao truncateTableDao;

    @Autowired
    private  TbFlowCompManufacturerDao tbFlowCompManufacturerDao;

    @Autowired
    private TbFlowCompVplPinNumberDao tbFlowCompVplPinNumberDao;

    @Autowired
    private CommonService commonService;

    @RequestMapping("/getNewestVersionTbTemplate")
    public Result getNewestVersionTbTemplate(@RequestBody String data) {

        return tbTemplateService.getNewestVersionTbTemplate(data);
    }

    @RequestMapping("/getNewestVersionTbTemplateForPush")
    public Result getNewestVersionTbTemplateForPush(@RequestBody String data) {

        return tbTemplateService.getNewestVersionTbTemplateForPush(data);
    }

    @RequestMapping("/getTaskFlow")
    public Result getTaskFlow(@RequestBody String data) {
        return taskCenterService.getTaskFlow(data);
    }

    @RequestMapping("/operateTaskFlow")
    public Result operateTaskFlow(@RequestBody String data) {
        return taskCenterService.operateTaskFlow(data);
    }

    //和TbFlowProcess的两个方法是一样的
    @RequestMapping("/getAllTask")
    public Result getAllTask(@RequestBody String data) {

        return taskCenterService.getAllTask(data);
    }

    @RequestMapping("/getMyTask")
    public Result getMyTask(@RequestBody String data) {
        return taskCenterService.getMyTask(data);
    }

    @RequestMapping("/deleteTaskData")
    public Result deleteTaskData(@RequestBody String data) {
        return taskCenterService.deleteTaskData(data);
    }

    @RequestMapping("/deleteTask")
    public Result deleteTask(@RequestBody String data) {
        return taskCenterService.deleteTask(data);
    }

    @RequestMapping("/authorizeApprover")
    public Result authorizeApprover(@RequestBody String data) {
        return taskCenterService.authorizeApprover(data);
    }

    @RequestMapping("/returnToPreNode")
    public Result returnToPreNode(@RequestBody String data) {
        return taskCenterService.returnToPreNode(data);
    }

    @RequestMapping("/getPartInfoFromPDM")
    public Result getPartInfoFromPDM(@RequestBody String data) {
        return taskCenterService.getPartInfoFromPDM(data);
    }

    @RequestMapping("/getPartInfoFormFlow")
    public Result getPartInfoFormFlow(@RequestBody String data) {
        return taskCenterService.getPartInfoFormFlow(data);
    }

    @PostMapping("/uploadPicture")
    public Result uploadPicture(HttpServletRequest req) {
        try {
            String userId = UserHeaderHolder.getUserId();
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            MultipartFile file = mRequest.getFile("file");
            String oldName = file.getOriginalFilename();
            String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
            if (!StringUtils.isBlank(env)) {
                Map<String, String> map = new HashMap<>();

                if (env.equals("dev")) {
                    //获取项目目录
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sdf.format(new Date());
                    File folder = new File(fileSaveUrl + "knowledgeBase\\" + format);
                    String filePath = "";
                    if (!folder.isDirectory()) {
                        folder.mkdirs();
                    }
                    file.transferTo(new File(folder, newName));
                    filePath = "knowledgeBase\\" + format + "\\" + newName;
                    map.put("name", newName);
                    map.put("oldName", oldName);
                    map.put("relatePath", filePath);
                    String base64 = "";
                    base64 = s3UploadFileService.getImageBase64FromUrl2(filePath,req);
                    map.put("imageBase64", CommonUtils.base64Prefix() + base64);
                    return ResultUtil.success(map);
                } else {
                    String address = s3UploadFileService.uploadFile("knowledgeBase", file);
                    if (address == null) {
                        return ResultUtil.error(500, "上传图片接口错误", null, null);
                    } else {
//                        String address = "11.jpg";
                        map.put("oldName", oldName);
                        map.put("name", newName);
                        map.put("relatePath", address);
                        map.put("url", url + "/" + fileBucket + "/" + address);
                        String base64 = "";
                        base64 = s3UploadFileService.getImageBase64FromUrl2(url + "/" + fileBucket + "/" + address,req);
                        map.put("imageBase64", CommonUtils.base64Prefix() + base64);
//                        map.put("url","http://192.168.31.11:2900/capacityApi/capacityFiles/pcb/2023-10-18/6d258ebc-399c-4533-9287-94af347cad65.png");
                        return ResultUtil.success(map);
                    }
                }
            } else {
                return ResultUtil.error(500, "配置文件yml中未定义参数：env", "", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @PostMapping("/uploadFile")
    public Result uploadFile(HttpServletRequest req) {
        try {
            String userId = UserHeaderHolder.getUserId();
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            MultipartFile file = mRequest.getFile("file");
            if (!StringUtils.isBlank(env)) {
                Map<String, String> map = new HashMap<>();
                String oldName = file.getOriginalFilename();
                if (env.equals("dev")) {
                    //获取项目目录
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sdf.format(new Date());
                    File folder = new File(fileSaveUrl + "knowledgeBase\\" + format);

                    String filePath = "";
                    if (!folder.isDirectory()) {
                        folder.mkdirs();
                    }

                    String newName = UUID.randomUUID().toString() +
                            oldName.substring(oldName.lastIndexOf("."), oldName.length());

                    file.transferTo(new File(folder, newName));
                    filePath = "knowledgeBase\\" + format + "\\" + newName;
                    map.put("name", newName);
                    map.put("oldName", oldName);
                    map.put("relatePath", filePath);
                    return ResultUtil.success(map);
                } else {

                    String secretKey = String.valueOf(UUID.randomUUID()).substring(0, 30);
                    SfsUtils.SfsFileData data = sfsUtils.upload(file, secretKey);
                    if (data == null) {
                        return ResultUtil.error(500, "上传接口返回data为空", null, null);
                    } else {
                        String fileSid = data.getFileSid();
//                        String fileSid = "10203";
                        if (StringUtils.isBlank(fileSid)) {
                            return ResultUtil.error(500, "上传接口返回data.fileSid为空", null, null);
                        }
                        map.put("oldName", oldName);
                        map.put("secretKey", secretKey);
                        map.put("fileSid", fileSid);
                        return ResultUtil.success(map);
                    }
                }
            } else {
                return ResultUtil.error(500, "配置文件yml中未定义参数：env", "", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    //@Transactional(transactionManager = "MysqlTransactionManager7")
    @PostMapping("/uploadFileVplAttr")
    public Result uploadFileVplAttr(HttpServletRequest req) {
        try {
            String userId = UserHeaderHolder.getUserId();
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            // 获取其他参数
            String flow_no = req.getParameter("flow_no");
            String flow_level = req.getParameter("flow_level");

            if (flow_no == null || flow_no.equals("") || flow_level == null || flow_level.equals("")) {
                return ResultUtil.error(500, "flow_no或flow_level为空", null, null);
            }

            int flow_levelnum = -1;
            if (flow_level != null && !flow_level.isEmpty()) {
                try {
                    // 将 flow_level_str 转换为整数
                    flow_levelnum = Integer.parseInt(flow_level);
                    // 现在您可以使用 flow_no 和 flow_level 进行后续操作
                } catch (NumberFormatException e) {
                    // 处理转换异常
                    e.printStackTrace();
                    // 可以选择抛出异常或返回错误信息
                    return ResultUtil.error(500, "flow_level转换失败", null, null);
                }
            }

            if (flow_levelnum == -1) {
                return ResultUtil.error(500, "flow_level转换失败", null, null);
            }
            //
            MultipartFile file = mRequest.getFile("file");
            String fileName = file.getOriginalFilename();
            //获取文件名
            String fileExtend = fileName.substring(fileName.lastIndexOf(".") + 1);

            List<TbFlowCompVplAttr> tbFlowCompVplAttrList = new ArrayList<>();
            List<TbFlowCompVplPinAttr> tbFlowCompVplPinAttrList = new ArrayList<>();

            String MaxBody_height = "";
            String MaxPin_length = "";
            String MinPin_length = "";

            String difficulty="";
            String equivalent_num = "";

            //判断只能上传xlsx和xlsm的文件
            if (fileExtend.equals("xlsx") || fileExtend.equals("xls") || fileExtend.equals("xmlx")) {
                //只有xls要解析
                if (fileExtend.equals("xlsx") || fileExtend.equals("xls"))
                {
                    //查询一下数据库的数据
                    List<TbFlowCompManufacturer> tbFlowCompManufacturers=tbFlowCompManufacturerDao.getTbFlowCompManufacturerByFlowNo(flow_no,1);

                    List<Map<String, String>> rowsCompAttr = ExcelUtils.parseExcel2(file, 0, 0);
                    if (rowsCompAttr != null && rowsCompAttr.size() > 0) {
                        for (Map<String, String> row : rowsCompAttr) {
                            TbFlowCompVplAttr tbFlowCompVplAttr = new TbFlowCompVplAttr();
                            tbFlowCompVplAttr.setFlow_no(flow_no);
                            tbFlowCompVplAttr.setFlow_level(flow_levelnum);
                            tbFlowCompVplAttr.setCreate_time(new Date());
                            tbFlowCompVplAttr.setCreate_user(UserHeaderHolder.getUserId());
                            tbFlowCompVplAttr.setManufacturer_type(row.get("厂家型号"));

                            boolean flag = false;
                            //增加判断,如果列表中没有就提示上传失败
                            if (tbFlowCompManufacturers != null && tbFlowCompManufacturers.size() > 0)
                            {
                                for (TbFlowCompManufacturer tbFlowCompManufacturer : tbFlowCompManufacturers) {
                                    if (tbFlowCompManufacturer.getManufacturer_type().equals(row.get("厂家型号"))) {
                                        flag = true;
                                    }
                                }
                            }
                            if(!flag)
                            {
                                return ResultUtil.error(500, row.get("厂家型号")+"不匹配", null, null);
                            }

                            tbFlowCompVplAttr.setMpn(row.get("MPN(VPL)"));
                            tbFlowCompVplAttr.setMcode(row.get("M-CODE(VPL)"));
                            tbFlowCompVplAttr.setPkg_name(row.get("VPL封装名"));
                            tbFlowCompVplAttr.setCoplanarity(row.get("共面度(mm)"));
                            tbFlowCompVplAttr.setWeight(row.get("重量(g)"));
                            tbFlowCompVplAttr.setAssembly_type(row.get("装联方式\n(smt/thd/pressfit/thd-pih/other/assem"));
                            tbFlowCompVplAttr.setBody_length(row.get("外形长(mm)"));
                            tbFlowCompVplAttr.setBody_width(row.get("外形宽(mm)"));
                            tbFlowCompVplAttr.setBody_height(row.get("外形高(mm)"));
                            tbFlowCompVplAttr.setBody_length_tol_p(row.get("外形长正公差(mm)"));
                            tbFlowCompVplAttr.setBody_length_tol_n(row.get("外形长负公差(mm)"));
                            tbFlowCompVplAttr.setBody_width_tol_p(row.get("外形宽正公差(mm)"));
                            tbFlowCompVplAttr.setBody_width_tol_n(row.get("外形宽负公差(mm)"));
                            tbFlowCompVplAttr.setBody_height_tol_p(row.get("外形高正公差(mm)"));
                            tbFlowCompVplAttr.setBody_height_tol_n(row.get("外形高负公差(mm)"));
                            tbFlowCompVplAttr.setStandoff(row.get("Standoff（表面贴片mm)"));
                            tbFlowCompVplAttr.setPth_diameter_min(row.get("最小压接孔成孔孔径(压接件mm)"));
                            tbFlowCompVplAttr.setVpl_creater(row.get("建库人员"));
                            tbFlowCompVplAttr.setApprover(row.get("审核人员"));
                            tbFlowCompVplAttr.setRemark(row.get("备注"));
                            tbFlowCompVplAttr.setIs_orientation(row.get("是否有极性"));
                            tbFlowCompVplAttr.setIs_high_step(row.get("物料高度是否有台阶"));
                            tbFlowCompVplAttr.setNumber(row.get("个数"));

                            tbFlowCompVplAttrList.add(tbFlowCompVplAttr);
                        }
                    }

                    List<Map<String, String>> rowsPinAttr = ExcelUtils.parseExcel2(file, 1, 0);
                    if (rowsPinAttr != null && rowsPinAttr.size() > 0) {
                        for (Map<String, String> row : rowsPinAttr) {
                            TbFlowCompVplPinAttr tbFlowCompVplPinAttr = new TbFlowCompVplPinAttr();
                            tbFlowCompVplPinAttr.setCreate_time(new Date());
                            tbFlowCompVplPinAttr.setCreate_user(UserHeaderHolder.getUserId());
                            tbFlowCompVplPinAttr.setFlow_no(flow_no);
                            tbFlowCompVplPinAttr.setFlow_level(flow_levelnum);
                            tbFlowCompVplPinAttr.setMpn(row.get("MPN(VPL)"));
                            tbFlowCompVplPinAttr.setPkg_name(row.get("VPL封装名"));
                            tbFlowCompVplPinAttr.setPin_min_pitch(row.get("最小引脚间距(mm)"));
                            tbFlowCompVplPinAttr.setPin_count(row.get("总引脚数量(个)"));
                            tbFlowCompVplPinAttr.setPin_number(row.get("引脚序号"));
                            tbFlowCompVplPinAttr.setPin_x_v(row.get("引脚X坐标"));//引脚X坐标(mm)
                            tbFlowCompVplPinAttr.setPin_y_v(row.get("引脚Y坐标"));//引脚Y坐标(mm)
                            tbFlowCompVplPinAttr.setPin_length(row.get("引脚外形尺寸长(mm)"));
                            tbFlowCompVplPinAttr.setPin_width(row.get("引脚外形尺寸宽(mm)"));
                            tbFlowCompVplPinAttr.setPin_length_tol_p(row.get("引脚外形尺寸长正公差(mm)"));
                            tbFlowCompVplPinAttr.setPin_length_tol_n(row.get("引脚外形尺寸长负公差(mm)"));
                            tbFlowCompVplPinAttr.setPin_width_tol_p(row.get("引脚外形尺寸宽正公差(mm)"));
                            tbFlowCompVplPinAttr.setPin_width_tol_n(row.get("引脚外形尺寸宽负公差(mm)"));
                            tbFlowCompVplPinAttr.setPin_type(row.get("引脚类型"));
                            tbFlowCompVplPinAttr.setPin_high(row.get("引脚长度(插件、压接)(mm)"));
                            tbFlowCompVplPinAttr.setPin_high_tol_p(row.get("引脚长度正公差（插件、压接)(mm)"));
                            tbFlowCompVplPinAttr.setPin_high_tol_n(row.get("引脚长度负公差（插件、压接)(mm)"));

                            tbFlowCompVplPinAttrList.add(tbFlowCompVplPinAttr);
                        }
                    }
                }
            } else {
                return ResultUtil.error(500, "只能上传xlsx和xlsm的文件", "", null);
            }

            AtomicBoolean isAllNA_maxSumValue = new AtomicBoolean(true);

            if (tbFlowCompVplAttrList != null && tbFlowCompVplAttrList.size() > 0) {
                Optional<Double> maxSumValue = tbFlowCompVplAttrList.stream()
                        .map(attr -> {
                            if(!attr.getBody_height().equals("N/A")&&!attr.getBody_height_tol_p().equals("N/A"))
                            {
                                isAllNA_maxSumValue.set(false);
                                // 处理字段A和B的空值及格式异常
                                double a = commonService.parseFieldWithDefault(attr.getBody_height()); // 空值或非法格式返回0
                                double b = commonService.parseFieldWithDefault(attr.getBody_height_tol_p());
                                return a + b; // 计算A+B的和
                            }else {
                                return null;  // 使用 null 标记无效值
                            }
                        })
                        .filter(Objects::nonNull)
                        .max(Double::compareTo); // 直接取最大值

                if(isAllNA_maxSumValue.get())
                {
                    MaxBody_height="N/A";
                }
                else
                {
                    // 若结果存在则赋值
                    if (maxSumValue.isPresent()) {
                        //MaxBody_height = String.valueOf(maxSumValue.get());
                        MaxBody_height = BigDecimal.valueOf(maxSumValue.get())
                                .setScale(2, RoundingMode.HALF_UP)
                                .toString();
                    }
                    else
                    {
                        MaxBody_height="N/A";
                    }
                }

                //取第一个数值
                TbFlowCompVplAttr tfcva = tbFlowCompVplAttrList.get(0);
                if (tfcva != null) {
                    Integer num = tbFlowCompVplAttrList.size();
                    double numberValue = commonService.parseFieldWithDefault(tfcva.getNumber());

                    // 使用BigDecimal进行精确计算，避免浮点数精度问题
                    BigDecimal totalValue = BigDecimal.valueOf(numberValue).multiply(BigDecimal.valueOf(num));
                    equivalent_num = totalValue.toString();

                    // 计算难度值，添加除零保护
                    if (num != 0) {
                        // 使用BigDecimal保持计算精度
                        BigDecimal denominator = BigDecimal.valueOf(num).multiply(BigDecimal.valueOf(1.5));
                        BigDecimal difficultyValue = totalValue.divide(denominator, 4, RoundingMode.HALF_UP);
                        difficulty = difficultyValue.toString();; // 或者toString()根据需要
                    } else {
                        // 处理num为0的情况，避免除零异常
                        difficulty = "0.0"; // 或其他默认值
                    }
                }
            }

            AtomicBoolean isAllNA_maxPinLength = new AtomicBoolean(true);
            AtomicBoolean isAllNA_minPinLength = new AtomicBoolean(true);

            if (tbFlowCompVplPinAttrList != null && tbFlowCompVplPinAttrList.size() > 0)
            {
                Optional<Double> maxPinLength = tbFlowCompVplPinAttrList.stream()
                        .map(attr -> {
                            if(!attr.getPin_high().equals("N/A")&&!attr.getPin_high_tol_p().equals("N/A"))
                            {
                                isAllNA_maxPinLength.set(false);
                                // 处理字段A和B的空值及格式异常
                                double a = commonService.parseFieldWithDefault(attr.getPin_high()); // 空值或非法格式返回0
                                double b = commonService.parseFieldWithDefault(attr.getPin_high_tol_p());
                                return a + b; // 计算A+B的和

                            }else {
                                return null;  // 使用 null 标记无效值
                            }
                        })
                        .filter(Objects::nonNull)
                        .max(Double::compareTo); // 直接取最大值

                if(isAllNA_maxPinLength.get())
                {
                    MaxPin_length="N/A";
                }
                else
                {
                    if (maxPinLength.isPresent())
                    {
                        //MaxPin_length = maxPinLength.get().toString();
                        MaxPin_length = BigDecimal.valueOf(maxPinLength.get())
                                .setScale(2, RoundingMode.HALF_UP)
                                .toString();
                    }
                    else
                    {
                        MaxPin_length="N/A";
                    }
                }

                Optional<Double> minPinLength = tbFlowCompVplPinAttrList.stream()
                        .map(attr -> {
                            if(!attr.getPin_high().equals("N/A")&&!attr.getPin_high_tol_n().equals("N/A"))
                            {
                                isAllNA_minPinLength.set(false);
                                // 处理字段A和B的空值及格式异常
                                double a = commonService.parseFieldWithDefault(attr.getPin_high()); // 空值或非法格式返回0
                                double b = commonService.parseFieldWithDefault(attr.getPin_high_tol_n());
                                return a - b; // 计算A+B的和
                            }
                            else
                            {
                                return null;
                            }
                        })
                        .filter(Objects::nonNull)
                        .min(Double::compareTo);

               if(isAllNA_minPinLength.get())
               {
                    MinPin_length="N/A";
               }
               else
               {
                   // 最终取值逻辑
                   if (minPinLength.isPresent()) {
                       //MinPin_length = minPinLength.get().toString();
                       MinPin_length = BigDecimal.valueOf(minPinLength.get())
                               .setScale(2, RoundingMode.HALF_UP)
                               .toString();
                   }
                   else
                   {
                       MinPin_length="N/A";
                   }
               }
            }

            if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {
                //处理原数据以及新增数据
                tbFlowCompVplAttrDao.deleteTbFlowCompVplAttrByFlowNo(flow_no);
                tbFlowCompVplPinAttrDao.deleteTbFlowCompVplPinAttrByFlowNo(flow_no);

                if (tbFlowCompVplAttrList != null && tbFlowCompVplAttrList.size() > 0) {
                    tbFlowCompVplAttrDao.insertTbFlowCompVplAttrBatch(tbFlowCompVplAttrList);
                }

                if (tbFlowCompVplPinAttrList != null && tbFlowCompVplPinAttrList.size() > 0) {
                    tbFlowCompVplPinAttrDao.insertTbFlowCompVplPinAttrBatch(tbFlowCompVplPinAttrList);
                }

                //更新流程节点
                TbFlowProcessDetail tbFlowProcessDetail = new TbFlowProcessDetail();
                tbFlowProcessDetail.setFlow_no(flow_no);
                tbFlowProcessDetail.setFlow_level(flow_levelnum);
                tbFlowProcessDetail.setMax_Body_height(MaxBody_height);
                tbFlowProcessDetail.setMax_Pin_length(MaxPin_length);
                tbFlowProcessDetail.setMin_Pin_length(MinPin_length);
                tbFlowProcessDetail.setDifficulty(difficulty);
                tbFlowProcessDetail.setEquivalent_num(equivalent_num);

                tbFlowProcessDetailDao.updateFlowProcessDetail(tbFlowProcessDetail);
            }

            //return ResultUtil.success("成功");

            if (!StringUtils.isBlank(env)) {
                Map<String, Object> map = new HashMap<>();
                String oldName = file.getOriginalFilename();
                if (env.equals("dev")) {
                    //获取项目目录
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sdf.format(new Date());
                    File folder = new File(fileSaveUrl + "knowledgeBase\\" + format);

                    String filePath = "";
                    if (!folder.isDirectory()) {
                        folder.mkdirs();
                    }

                    String newName = UUID.randomUUID().toString() +
                            oldName.substring(oldName.lastIndexOf("."), oldName.length());

                    file.transferTo(new File(folder, newName));
                    filePath = "knowledgeBase\\" + format + "\\" + newName;
                    map.put("name", newName);
                    map.put("oldName", oldName);
                    map.put("relatePath", filePath);

                    if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {
                        map.put("compVplAttr", tbFlowCompVplAttrList);
                        map.put("compVplPinAttr", tbFlowCompVplPinAttrList);
                        map.put("max_Body_height", MaxBody_height);
                        map.put("max_Pin_length", MaxPin_length);
                        map.put("min_Pin_length", MinPin_length);
                    }

                    return ResultUtil.success(map);
                } else {
                    String secretKey = String.valueOf(UUID.randomUUID()).substring(0, 30);
                    SfsUtils.SfsFileData data = sfsUtils.upload(file, secretKey);
                    if (data == null) {
                        return ResultUtil.error(500, "上传接口返回data为空", null, null);
                    } else {
                        String fileSid = data.getFileSid();
                        if (StringUtils.isBlank(fileSid)) {
                            return ResultUtil.error(500, "上传接口返回data.fileSid为空", null, null);
                        }
                        map.put("oldName", oldName);
                        map.put("secretKey", secretKey);
                        map.put("fileSid", fileSid);

                        if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {
                            map.put("compVplAttr", tbFlowCompVplAttrList);
                            map.put("compVplPinAttr", tbFlowCompVplPinAttrList);
                            map.put("max_Body_height", MaxBody_height);
                            map.put("max_Pin_length", MaxPin_length);
                            map.put("min_Pin_length", MinPin_length);
                        }

                        return ResultUtil.success(map);
                    }
                }
            } else {
                return ResultUtil.error(500, "配置文件yml中未定义参数：env", "", null);
            }

        } catch (Exception e) {
            e.printStackTrace();
            //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Transactional(transactionManager = "MysqlTransactionManager7")
    @PostMapping("/uploadFilePkg")
    public Result uploadFilePkg(HttpServletRequest req) {
        try {
            String userId = UserHeaderHolder.getUserId();
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            // 获取其他参数
            String flow_no = req.getParameter("flow_no");
            String flow_level = req.getParameter("flow_level");
            String pkg_name = req.getParameter("pkg_name");

            if (flow_no == null || flow_no.equals("") || flow_level == null || flow_level.equals("")) {
                return ResultUtil.error(500, "flow_no或flow_level为空", null, null);
            }
            if(pkg_name == null || pkg_name.isEmpty())
            {
                return ResultUtil.error(500, "pkg_name不可以为空", null, null);
            }

            int flow_levelnum = -1;
            if (flow_level != null && !flow_level.isEmpty()) {
                try {
                    // 将 flow_level_str 转换为整数
                    flow_levelnum = Integer.parseInt(flow_level);
                    // 现在您可以使用 flow_no 和 flow_level 进行后续操作
                } catch (NumberFormatException e) {
                    // 处理转换异常
                    e.printStackTrace();
                    // 可以选择抛出异常或返回错误信息
                    return ResultUtil.error(500, "flow_level转换失败", null, null);
                }
            }

            if (flow_levelnum == -1) {
                return ResultUtil.error(500, "flow_level转换失败", null, null);
            }
            //20250314 增加判断,目前先判断封装名和文件里面是否一样.所以要先获取一下当前节点的信息
            List<TbFlowCompPkg> dbList = tbFlowCompPkgDao.getTbFlowCompPkgByFlowNo(flow_no, flow_levelnum);
            if (dbList == null || dbList.size() <= 0) {
                return ResultUtil.error(500, "当前节点信息不存在,请刷新页面", null, null);
            }
            TbFlowCompPkg dbTbFlowCompPkg=new TbFlowCompPkg();
            dbTbFlowCompPkg=dbList.get(0);


            MultipartFile file = mRequest.getFile("file");
            String fileName = file.getOriginalFilename();
            //获取文件名
            String fileExtend = fileName.substring(fileName.lastIndexOf(".") + 1);

            List<TbFlowCompPkg> tbFlowCompPkgList = new ArrayList<>();
            List<TbFlowCompVplPinNumber> tbFlowCompVplPinNumberList=new ArrayList<>();

            //判断只能上传xlsx和xlsm的文件
            if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {
                List<Map<String, String>> rowsCompAttr = ExcelUtils.parseExcel2(file, 0, 0);
                if (rowsCompAttr != null && rowsCompAttr.size() > 0) {
                    Map<String, String> row = rowsCompAttr.get(0);
                    TbFlowCompPkg tbFlowCompPkg = new TbFlowCompPkg();
                    tbFlowCompPkg.setFlow_no(flow_no);
                    tbFlowCompPkg.setFlow_level(flow_levelnum);
                    tbFlowCompPkg.setUpdate_time(new Date());
                    tbFlowCompPkg.setUpdate_user(UserHeaderHolder.getUserId());

                    //String pkgName=dbTbFlowCompPkg.getPkg_name();
                    String pkgName=pkg_name;
                    //update log 修改需求 20250826 为空就不判断
                    //if(pkgName==null|| pkgName.isEmpty())
                    //{
                    //    return ResultUtil.error(500, "节点封装名为空,请检查", "", null);
                    //}

                    //if(!dbTbFlowCompPkg.getPkg_name().equals(row.get("封装名")))
                    //{
                    //    return ResultUtil.error(500, "封装名不一致,请检查", "", null);
                    //}
                    if(!pkgName.equalsIgnoreCase(row.get("封装名")))
                    {
                        return ResultUtil.error(500, "封装名不一致,请检查", "", null);
                    }

                    //tbFlowCompPkg.setPkg_name(row.get("封装名"));
                    if(dbTbFlowCompPkg.getAssembly_type()==null|| dbTbFlowCompPkg.getAssembly_type().isEmpty())
                    {
                        tbFlowCompPkg.setAssembly_type(row.get("装联方式"));
                    }
                    tbFlowCompPkg.setPkg_name(row.get("封装名"));
                    tbFlowCompPkg.setPad_airgap_min(row.get("焊盘最小airgap"));
                    tbFlowCompPkg.setBody_length(row.get("封装外形长mil"));
                    tbFlowCompPkg.setBody_width(row.get("封装外形宽mil"));
                    tbFlowCompPkg.setFoot_num(row.get("总引脚数量"));

                    tbFlowCompPkg.setIs_size_not_fit(convertYesToNumber(row.get("是否钢网比焊盘大或小")));
                    tbFlowCompPkg.setIs_size_not_fit(convertYesToNumber(row.get("是否钢网分网格设计")));
                    tbFlowCompPkg.setIs_twins_design(convertYesToNumber(row.get("是否引脚焊盘连体设计")));
                    tbFlowCompPkg.setIs_special_design(convertYesToNumber(row.get("是否阻焊特殊设计")));
                    tbFlowCompPkg.setIs_window_open(convertYesToNumber(row.get("是否整体阻焊开窗")));
                    tbFlowCompPkg.setIs_small_air_gap(convertYesToNumber(row.get("是否插件孔盘最小air gap小于32mil")));
                    tbFlowCompPkg.setPitch_o2c_x(row.get("封装原点x（相对矩形中心）"));
                    tbFlowCompPkg.setPitch_o2c_y(row.get("封装原点y\n（相对矩形中心）"));

                    tbFlowCompPkgList.add(tbFlowCompPkg);

                    tbFlowCompPkgDao.updateTbFlowCompPkgByFlowNo(tbFlowCompPkg);

                } else {
                    return ResultUtil.error(500, "模板中封装参数没有有效数据,请检查", "", null);
                }

                List<Map<String, String>> rowsPinNumber = ExcelUtils.parseExcel2(file, 1, 0);
                if (rowsPinNumber != null && rowsPinNumber.size() > 0) {
                    for (Map<String, String> row : rowsPinNumber)
                    {
                        //Map<String, String> row = rowsPinNumber.get(0);
                        TbFlowCompVplPinNumber tbFlowCompVplPinNumber = new TbFlowCompVplPinNumber();
                        tbFlowCompVplPinNumber.setFlow_no(flow_no);
                        tbFlowCompVplPinNumber.setFlow_level(flow_levelnum);
                        tbFlowCompVplPinNumber.setUpdate_time(new Date());
                        tbFlowCompVplPinNumber.setUpdate_user(UserHeaderHolder.getUserId());

                        if (row.get("封装名") == null || row.get("封装名").isEmpty()) {
                            return ResultUtil.error(500, "封装名为空,请检查", "", null);
                        }

                        if(!pkg_name.equalsIgnoreCase(row.get("封装名")))
                        {
                            return ResultUtil.error(500, "封装名不一致,请检查", "", null);
                        }

                        //if (!row.get("封装名").equals(dbTbFlowCompPkg.getPkg_name())) {
                        //    return ResultUtil.error(500, "封装名不一致,请检查", "", null);
                        //}

                        tbFlowCompVplPinNumber.setPkg_name(row.get("封装名"));
                        tbFlowCompVplPinNumber.setPad_name(row.get("pad名称"));
                        tbFlowCompVplPinNumber.setPin_number(row.get("引脚序号"));
                        tbFlowCompVplPinNumber.setPin_x(row.get("引脚X坐标"));
                        tbFlowCompVplPinNumber.setPin_y(row.get("引脚Y坐标"));
                        tbFlowCompVplPinNumber.setRegular_pad_length(row.get("焊盘尺寸长mil"));
                        tbFlowCompVplPinNumber.setRegular_pad_width(row.get("焊盘尺寸宽"));
                        tbFlowCompVplPinNumber.setDrill_hole_length(row.get("成孔孔尺寸长"));
                        tbFlowCompVplPinNumber.setDrill_hole_width(row.get("成孔尺寸宽"));
                        tbFlowCompVplPinNumber.setDrill_hole_tol_p(row.get("压接孔正公差"));
                        tbFlowCompVplPinNumber.setDrill_hole_tol_n(row.get("压接孔负公差"));
                        tbFlowCompVplPinNumber.setAnti_pad_size(row.get("反焊盘antipad"));
                        tbFlowCompVplPinNumber.setThermal_pad_size(row.get("热焊盘thermalpad"));

                        tbFlowCompVplPinNumberList.add(tbFlowCompVplPinNumber);
                    }
                    tbFlowCompVplPinNumberDao.deleteTbFlowCompVplPinNumberByFlowNo(flow_no);
                    tbFlowCompVplPinNumberDao.insertTbFlowCompVplPinNumberBatch(tbFlowCompVplPinNumberList);
                } else {
                    return ResultUtil.error(500, "模板中引脚编号没有有效数据,请检查", "", null);
                }



            } else {
                return ResultUtil.error(500, "只能上传xlsx和xls的文件", "", null);
            }

            if (!StringUtils.isBlank(env)) {
                Map<String, Object> map = new HashMap<>();
                String oldName = file.getOriginalFilename();
                if (env.equals("dev")) {
                    //获取项目目录
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sdf.format(new Date());
                    File folder = new File(fileSaveUrl + "knowledgeBase\\" + format);

                    String filePath = "";
                    if (!folder.isDirectory()) {
                        folder.mkdirs();
                    }

                    String newName = UUID.randomUUID().toString() +
                            oldName.substring(oldName.lastIndexOf("."), oldName.length());

                    file.transferTo(new File(folder, newName));
                    filePath = "knowledgeBase\\" + format + "\\" + newName;
                    map.put("name", newName);
                    map.put("oldName", oldName);
                    map.put("relatePath", filePath);

                    if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {
                        map.put("compPkg", tbFlowCompPkgList);
                    }

                    return ResultUtil.success(map);
                } else {
                    String secretKey = String.valueOf(UUID.randomUUID()).substring(0, 30);
                    SfsUtils.SfsFileData data = sfsUtils.upload(file, secretKey);
                    if (data == null) {
                        return ResultUtil.error(500, "上传接口返回data为空", null, null);
                    } else {
                        String fileSid = data.getFileSid();
                        if (StringUtils.isBlank(fileSid)) {
                            return ResultUtil.error(500, "上传接口返回data.fileSid为空", null, null);
                        }
                        map.put("oldName", oldName);
                        map.put("secretKey", secretKey);
                        map.put("fileSid", fileSid);

                        if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {
                            map.put("compPkg", tbFlowCompPkgList);
                        }

                        return ResultUtil.success(map);
                    }
                }
            } else {
                return ResultUtil.error(500, "配置文件yml中未定义参数：env", "", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    public static String convertYesToNumber(String input) {
        if ("是".equals(input)) {  // 避免空指针，优先将常量放前面[3](@ref)
            return "1";
        } else {
            return "0";
        }
    }

    @PostMapping("/downloadH3CFile")
    public Result downloadH3CFile(Integer fileId) {
        try {
            if (fileId == null) {
                return ResultUtil.error(500, "参数fileId为空", "param fileId is null", null);
            }
            TbKnowledgeBaseFile tbKnowledgeBaseFile = tbKnowledgeBaseFileDao.getTbKnowledgeBaseFileById(fileId);

            if (!StringUtils.isBlank(env))
            {
                if(env.equals("dev"))
                {
                    // 本地下载
                    java.io.File file = new java.io.File(fileSaveUrl + tbKnowledgeBaseFile.getFile_relate_path());   //URL url = new URL(src);
                    if (!file.exists() || file.length() == 0) {
                        return ResultUtil.error(500, "文件不存在", "File Not Exist", null);
                    }
                    byte[] data = null;
                    InputStream in = new FileInputStream(file);  //InputStream in = url.openStream();
                    data = new byte[in.available()];
                    in.read(data);
                    in.close();
                    Base64.Encoder encoder = Base64.getEncoder();
                    String base64 = encoder.encodeToString(data);

                    Map<String, Object> map = new HashMap<>();
                    map.put("base64", base64);
                    map.put("fileName", tbKnowledgeBaseFile.getFile_name());
                    return ResultUtil.success(map);
                }
                else
                {
                    String fileSid = tbKnowledgeBaseFile.getFile_sid();
                    String secretKey = tbKnowledgeBaseFile.getSecret_key();
                    InputStream inputStream = sfsUtils.download(fileSid, secretKey);
                    byte[] data = null;
                    data = new byte[inputStream.available()];
                    inputStream.read(data);
                    inputStream.close();
                    Base64.Encoder encoder = Base64.getEncoder();
                    String base64 = encoder.encodeToString(data);
                    Map<String, Object> map = new HashMap<>();
                    map.put("base64", base64);
                    map.put("fileName", tbKnowledgeBaseFile.getFile_name());
                    return ResultUtil.success(map);
                }
            }
            else {
                return ResultUtil.error(500, "配置文件yml中未定义参数：env", "", null);
            }

        } catch (Exception e) {
            return ResultUtil.error(500, "downloadH3CFile Exception:" + e.getMessage(), e.getMessage(), null);
        }
    }

    @PostMapping("/downloadH3CFile2")
    public Result downloadH3CFile2(String fileId,String fileSId) {
        try {
            if (fileId == null || fileSId==null || fileId.isEmpty() || fileSId.isEmpty() ) {
                return ResultUtil.error(500, "参数fileId或者fileSId为空", "param fileId is null", null);
            }

            TbKnowledgeBaseFile tbKnowledgeBaseFile = tbKnowledgeBaseFileDao.getTbKnowledgeBaseFileBySecretkey(fileId);
            //String fileSid = tbKnowledgeBaseFile.getFile_sid();
            //String secretKey = tbKnowledgeBaseFile.getSecret_key();
            InputStream inputStream = sfsUtils.download(fileSId, fileId);
            byte[] data = null;
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
            Base64.Encoder encoder = Base64.getEncoder();
            String base64 = encoder.encodeToString(data);
            Map<String, Object> map = new HashMap<>();
            map.put("base64", base64);
            if(tbKnowledgeBaseFile!=null)
            {
                map.put("fileName", tbKnowledgeBaseFile.getFile_name());
            }
            else
            {
                map.put("fileName",fileId );
            }

            return ResultUtil.success(map);
        } catch (Exception e) {
            return ResultUtil.error(500, "downloadH3CFile2 Exception:" + e.getMessage(), e.getMessage(), null);
        }
    }

    @PostMapping("/getTaskTemplateDataList")
    public Result getTaskTemplateDataList(@RequestBody String data) {
        try {
            JSONObject dataObject = JSON.parseObject(data);
            // 提取conditions
            JSONArray conditionsArray = dataObject.getJSONArray("conditions");
            List<Map<String, String>> keyValueMaps = new ArrayList<>();

            if (conditionsArray != null) {
                for (int i = 0; i < conditionsArray.size(); i++) {
                    JSONObject condition = conditionsArray.getJSONObject(i);
                    Map<String, String> map = new HashMap<>();
                    if (StringUtils.isEmpty(condition.getString("key")) && !StringUtils.isEmpty(condition.getString("value"))) {
                        return ResultUtil.error(500, "错误的键值对nullkey-to-value", "wrong key-value", null);
                    }
                    map.put("key", condition.getString("key"));
                    map.put("value", condition.getString("value"));
                    keyValueMaps.add(map);
                }
            }
            String templateType = dataObject.containsKey("templateType") ? dataObject.getString("templateType") : null;

            if (templateType == null && templateType.isEmpty()) {
                return ResultUtil.error(500, "模板类型不能为空", "", null);
            } else {
                return ResultUtil.success(commonService.getTaskTemplateData(templateType, keyValueMaps));
            }


        } catch (Exception e) {
            return ResultUtil.error(500, e.getMessage(), "", null);
        }


    }

    @RequestMapping("/cancelTask")
    public Result cancelTask(@RequestBody String data) {
        return taskCenterService.cancelTask(data);
    }

    @RequestMapping("/deleteCompManufacturer")
    public Result deleteCompManufacturer(@RequestBody String data) {
        return taskCenterService.deleteCompManufacturer(data);
    }

    @PostMapping("/outputParamTemplate")
    public Result outputParamTemplate(@RequestBody String data) throws IOException {

        JSONObject dataObject = JSON.parseObject(data);
        // 提取conditions
        String type = dataObject.getString("type");

        if (type == null || type.isEmpty()) {
            return ResultUtil.error(500, "模板类型不能为空", "", null);
        }

        if (type.equals("vplAttr")) {
            Map<String, List<String>> listMap = new LinkedHashMap<>();

            List<String> compList = new ArrayList<>();
            compList.add("厂家型号");
            compList.add("MPN(VPL)");
            compList.add("M-CODE(VPL)");
            compList.add("VPL封装名");
            compList.add("共面度(mm)");
            compList.add("重量(g)");
            compList.add("装联方式\n(smt/thd/pressfit/thd-pih/other/assem");
            compList.add("外形长(mm)");
            compList.add("外形宽(mm)");
            compList.add("外形高(mm)");
            compList.add("外形长正公差(mm)");
            compList.add("外形长负公差(mm)");
            compList.add("外形宽正公差(mm)");
            compList.add("外形宽负公差(mm)");
            compList.add("外形高正公差(mm)");
            compList.add("外形高负公差(mm)");
            compList.add("Standoff（表面贴片mm)");
            compList.add("最小压接孔成孔孔径(压接件mm)");
            compList.add("建库人员");
            compList.add("审核人员");
            compList.add("备注");
            compList.add("是否有极性");
            compList.add("物料高度是否有台阶");
            compList.add("个数");
            listMap.put("器件属性", compList);

            List<String> pinList = new ArrayList<>();
            pinList.add("MPN(VPL)");
            pinList.add("VPL封装名");
            pinList.add("最小引脚间距(mm)");
            pinList.add("总引脚数量(个)");
            pinList.add("引脚序号");
            pinList.add("引脚X坐标");//引脚X坐标(mm)
            pinList.add("引脚Y坐标");//引脚Y坐标(mm)
            pinList.add("引脚外形尺寸长(mm)");
            pinList.add("引脚外形尺寸宽(mm)");
            pinList.add("引脚外形尺寸长正公差(mm)");
            pinList.add("引脚外形尺寸长负公差(mm)");
            pinList.add("引脚外形尺寸宽正公差(mm)");
            pinList.add("引脚外形尺寸宽负公差(mm)");
            pinList.add("引脚类型");
            pinList.add("引脚长度(插件、压接)(mm)");
            pinList.add("引脚长度正公差（插件、压接)(mm)");
            pinList.add("引脚长度负公差（插件、压接)(mm)");

            listMap.put("PIN属性", pinList);

            Result result = commonService.outputParamTemplate2(listMap, "VPL属性表模板");
            if (result.getCode().equals(200)) {
                try {
                    String filepath = (String) result.getData();
                    File file = new File(filepath);
                    String fname = file.getName();
                    byte[] bytedata = null;
                    InputStream in = new FileInputStream(file);
                    bytedata = new byte[in.available()];
                    in.read(bytedata);
                    in.close();
                    Base64.Encoder encoder = Base64.getEncoder();
                    String base64 = encoder.encodeToString(bytedata);

                    Map<String, Object> map = new HashMap<>();
                    map.put("base64", base64);
                    map.put("fileName", fname);
                    return ResultUtil.success(map);
                } catch (Exception e) {
                    e.printStackTrace();
                    return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
                }
            } else {
                return result;
            }
        }
        else if (type.equals("pkg"))
        {
            Map<String, List<String>> listMap = new LinkedHashMap<>();

            List<String> pkgList = new ArrayList<>();
            pkgList.add("封装名");
            pkgList.add("装联方式");
            pkgList.add("焊盘最小airgap");
            pkgList.add("封装外形长mil");
            pkgList.add("封装外形宽mil");
            pkgList.add("总引脚数量");
            pkgList.add("是否钢网比焊盘大或小");
            pkgList.add("是否钢网分网格设计");
            pkgList.add("是否引脚焊盘连体设计");
            pkgList.add("是否阻焊特殊设计");
            pkgList.add("是否整体阻焊开窗");
            pkgList.add("是否插件孔盘最小air gap小于32mil");
            pkgList.add("封装原点x（相对矩形中心）");
            pkgList.add("封装原点y\n（相对矩形中心）");

            listMap.put("封装参数", pkgList);

            List<String> pinList = new ArrayList<>();
            pinList.add("封装名");
            pinList.add("pad名称");
            pinList.add("引脚序号");
            pinList.add("引脚X坐标");
            pinList.add("引脚Y坐标");
            pinList.add("焊盘尺寸长mil");
            pinList.add("焊盘尺寸宽");
            pinList.add("成孔孔尺寸长");
            pinList.add("成孔尺寸宽");
            pinList.add("压接孔正公差");
            pinList.add("压接孔负公差");
            pinList.add("反焊盘antipad");
            pinList.add("热焊盘thermalpad");

            listMap.put("Pin数据", pinList);


            List<String> PLACE_BOUND_TOPList = new ArrayList<>();
            PLACE_BOUND_TOPList.add("package_name");
            PLACE_BOUND_TOPList.add("type");
            PLACE_BOUND_TOPList.add("loop_label");
            PLACE_BOUND_TOPList.add("xs");
            PLACE_BOUND_TOPList.add("ys");
            PLACE_BOUND_TOPList.add("xe");
            PLACE_BOUND_TOPList.add("ye");
            PLACE_BOUND_TOPList.add("xc");
            PLACE_BOUND_TOPList.add("yc");
            PLACE_BOUND_TOPList.add("sym_num");
            PLACE_BOUND_TOPList.add("width");
            PLACE_BOUND_TOPList.add("radius");
            PLACE_BOUND_TOPList.add("clockwise");

            listMap.put("PLACE_BOUND_TOP", pkgList);

            List<String> ASSEMBLY_TOPList = new ArrayList<>();
            ASSEMBLY_TOPList.add("package_name");
            ASSEMBLY_TOPList.add("type");
            ASSEMBLY_TOPList.add("loop_label");
            ASSEMBLY_TOPList.add("xs");
            ASSEMBLY_TOPList.add("ys");
            ASSEMBLY_TOPList.add("xe");
            ASSEMBLY_TOPList.add("ye");
            ASSEMBLY_TOPList.add("xc");
            ASSEMBLY_TOPList.add("yc");
            ASSEMBLY_TOPList.add("sym_num");
            ASSEMBLY_TOPList.add("width");
            ASSEMBLY_TOPList.add("radius");
            ASSEMBLY_TOPList.add("clockwise");

            listMap.put("ASSEMBLY_TOP", pkgList);

            Result result = commonService.outputParamTemplate2(listMap, "封装参数模板");
            if (result.getCode().equals(200)) {
                try {
                    String filepath = (String) result.getData();
                    File file = new File(filepath);
                    String fname = file.getName();
                    byte[] bytedata = null;
                    InputStream in = new FileInputStream(file);
                    bytedata = new byte[in.available()];
                    in.read(bytedata);
                    in.close();
                    Base64.Encoder encoder = Base64.getEncoder();
                    String base64 = encoder.encodeToString(bytedata);

                    Map<String, Object> map = new HashMap<>();
                    map.put("base64", base64);
                    map.put("fileName", fname);
                    return ResultUtil.success(map);
                } catch (Exception e) {
                    e.printStackTrace();
                    return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
                }
            } else {
                return result;
            }
        }
        else if (type.equals("device")) {
            Map<String, List<String>> listMap = new LinkedHashMap<>();

            List<String> compList = new ArrayList<>();
            compList.add("器件专用");
            compList.add("器件编码");
            compList.add("器件封装");
            compList.add("装联方式");
            compList.add("器件大类");
            compList.add("器件小类");
            compList.add("设计阶段");
            compList.add("级别");
            compList.add("工艺知识checklist");
            compList.add("检查方法");
            compList.add("规则来源");
            compList.add("图片");
            compList.add("附件");

            listMap.put("器件工艺知识", compList);

            Result result = commonService.outputParamTemplate2(listMap, "器件工艺知识模板");
            if (result.getCode().equals(200)) {
                try {
                    String filepath = (String) result.getData();
                    File file = new File(filepath);
                    String fname = file.getName();
                    byte[] bytedata = null;
                    InputStream in = new FileInputStream(file);
                    bytedata = new byte[in.available()];
                    in.read(bytedata);
                    in.close();
                    Base64.Encoder encoder = Base64.getEncoder();
                    String base64 = encoder.encodeToString(bytedata);

                    Map<String, Object> map = new HashMap<>();
                    map.put("base64", base64);
                    map.put("fileName", fname);
                    return ResultUtil.success(map);
                } catch (Exception e) {
                    e.printStackTrace();
                    return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
                }
            } else {
                return result;
            }
        }
        else if (type.equals("design")) {
            Map<String, List<String>> listMap = new LinkedHashMap<>();

            List<String> compList = new ArrayList<>();
            compList.add("产品线");
            compList.add("单板类型");
            compList.add("工艺大类");
            compList.add("工艺小类");
            compList.add("工艺子类");
            compList.add("设计阶段");
            compList.add("级别");
            compList.add("工艺知识checklist");
            compList.add("检查方法");
            compList.add("规则来源");
            compList.add("图片");
            compList.add("附件");

            listMap.put("工艺规范知识", compList);

            Result result = commonService.outputParamTemplate2(listMap, "工艺规范知识模板");
            if (result.getCode().equals(200)) {
                try {
                    String filepath = (String) result.getData();
                    File file = new File(filepath);
                    String fname = file.getName();
                    byte[] bytedata = null;
                    InputStream in = new FileInputStream(file);
                    bytedata = new byte[in.available()];
                    in.read(bytedata);
                    in.close();
                    Base64.Encoder encoder = Base64.getEncoder();
                    String base64 = encoder.encodeToString(bytedata);

                    Map<String, Object> map = new HashMap<>();
                    map.put("base64", base64);
                    map.put("fileName", fname);
                    return ResultUtil.success(map);
                } catch (Exception e) {
                    e.printStackTrace();
                    return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
                }
            } else {
                return result;
            }
        }
        else {
            return ResultUtil.error(500, "暂未支持的模板类型", "", null);
        }
    }


    @RequestMapping("/getFlowRecords")
    public Result getFlowRecords(@RequestBody String data) {
        return taskCenterService.getFlowRecords(data);
    }

    @RequestMapping("/getFlowTemplateInfoByFlowNo")
    public Result getFlowTemplateInfoByFlowNo(@RequestBody String data) {
        return taskCenterService.getFlowTemplateInfoByFlowNo(data);
    }

    @RequestMapping("/getFlowTemplateInfoByFlowNo2")
    public Result getFlowTemplateInfoByFlowNo2(@RequestBody String data) {
        return taskCenterService.getFlowTemplateInfoByFlowNo2(data);
    }
    @RequestMapping("/scheduledCreateVplFlow")
    public Result scheduledCreateVplFlow(@RequestBody String data) {
         taskCenterService.scheduledCreateVplFlow();
        return null;
    }

    @RequestMapping("/scheduledSendDataToVpl")
    public Result scheduledSendDataToVpl(@RequestBody String data) {
        taskCenterService.scheduledSendDataToVpl();
        return null;
    }

    @RequestMapping("/getCompPkgInfoByCompPkg")
    public Result getCompPkgInfoByCompPkg(@RequestBody String data) {
        return taskCenterService.getCompPkgInfoByCompPkg(data);
    }

    @RequestMapping("/getPkgByCompCode")
    public Result getPkgByCompCode(@RequestBody String data) {
        return taskCenterService.getPkgByCompCode(data);
    }

    @RequestMapping("/deleteKnowledgeBaseByKey")
    public Result deleteKnowledgeBaseByKey(@RequestBody String data) {
        return taskCenterService.deleteKnowledgeBaseByKey(data);
    }

    @RequestMapping("/truncateFlow")
    public Result truncateFlow(@RequestBody String data) {
        truncateTableDao.truncateFlow1();
        truncateTableDao.truncateFlow2();
        truncateTableDao.truncateFlow3();
        truncateTableDao.truncateFlow4();
        truncateTableDao.truncateFlow5();
        truncateTableDao.truncateFlow6();
        truncateTableDao.truncateFlow7();
        truncateTableDao.truncateFlow8();
        truncateTableDao.truncateFlow9();
        truncateTableDao.truncateFlow10();
        truncateTableDao.truncateFlow11();
        truncateTableDao.truncateFlow12();
        truncateTableDao.truncateFlow13();
        return ResultUtil.success("OK") ;
    }


    @PostMapping("/getAllBoardParams")
    public Result getAllBoardParams() {
        try {
            //JSONObject params = new JSONObject();
            //String md5Sign = CommonUtils.encryptToMD5(CommonUtils.encryptToMD5(sign));
            //params.put("signature", md5Sign);
            //String keyRes1 = HttpUtil.sendPostJson(getAllBoardParamsApi, params);
            //JSONObject resObj1 = JSONObject.parseObject(keyRes1);

            String md5Sign = "6244832a706bbb2c81fb093367027f56";
            MultipartEntityBuilder params = MultipartEntityBuilder.create();
            params.addTextBody("signature", md5Sign);
            String res = HttpUtil.sendPostFormData(getAllBoardParamsApi, params);
            JSONObject jsonObjectRes = JSON.parseObject(res);
            if (jsonObjectRes.getInteger("code") == 200) {
                JSONArray jsonArray = jsonObjectRes.getJSONArray("data");
                JSONArray newArray = new JSONArray();

                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject param = jsonArray.getJSONObject(i);

                    Integer boardParamId = param.getInteger("boardParamTypeId");
                    if (boardParamId != null && (boardParamId == 3 || boardParamId == 5 || boardParamId == 6 || boardParamId == 10)) {
                        newArray.add(jsonArray.get(i));
                    }
                }
                return ResultUtil.success(newArray);
            }
            else
            {
                return ResultUtil.error(jsonObjectRes.getInteger("code"), jsonObjectRes.getString("msg"), jsonObjectRes.getString("msg"), null);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }


    @PostMapping("/getAllBoardParamsBy0310AndVersion")
    public Result getAllBoardParamsBy0310AndVersion(HttpServletRequest req) {
        try {
            //JSONObject params = new JSONObject();
            //String md5Sign = CommonUtils.encryptToMD5(CommonUtils.encryptToMD5(sign));
            //params.put("signature", md5Sign);
            //String keyRes1 = HttpUtil.sendPostJson(getAllBoardParamsApi, params);
            //JSONObject resObj1 = JSONObject.parseObject(keyRes1);

            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            String board0301 = mRequest.getParameter("board0301");
            String version = mRequest.getParameter("version");

            String md5Sign = "6244832a706bbb2c81fb093367027f56";
            MultipartEntityBuilder params = MultipartEntityBuilder.create();
            params.addTextBody("signature", md5Sign);
            params.addTextBody("board0301", board0301);
            params.addTextBody("version", version);

            String res = HttpUtil.sendPostFormData(getAllBoardParamsBy0310AndVersionapi, params);
            JSONObject jsonObjectRes = JSON.parseObject(res);//

            if (jsonObjectRes.getInteger("code") == 200) {
                //JSONArray jsonArray = jsonObjectRes.getJSONArray("data");

                //return ResultUtil.success(jsonArray);

                ObjectMapper mapper = new ObjectMapper();
                JsonNode jsonArray = mapper.readTree(jsonObjectRes.getString("data"));

                List<JsonNode> mergedList = new ArrayList<>();

                for (JsonNode node : jsonArray) {
                    int typeId = node.get("boardParamTypeId").asInt();
                    if (typeId == 3 || typeId == 5|| typeId == 6|| typeId == 10) {
                        JsonNode paramList = node.get("boardParamList");
                        if (paramList != null && paramList.isArray()) {
                            paramList.forEach(mergedList::add);
                        }
                    }
                }
                return ResultUtil.success(mergedList);
            }
            else
            {
                return ResultUtil.error(jsonObjectRes.getInteger("code"), jsonObjectRes.getString("msgCn"), jsonObjectRes.getString("msgEn"), null);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }


    @RequestMapping("/getKnowledgeBaseNotice")
    public Result getKnowledgeBaseNotice(@RequestBody String data) {
        return taskCenterService.getKnowledgeBaseNotice(data);
    }

    @RequestMapping("/updateKnowledgeBaseNotice")
    public Result updateKnowledgeBaseNotice(@RequestBody String data) {
        return taskCenterService.updateKnowledgeBaseNotice(data);
    }

    @RequestMapping("/scheduledUpdatePkgName")
    public Result scheduledUpdatePkgName(@RequestBody String data) {
        taskCenterService.scheduledUpdatePkgName();
        return null;
    }


    @RequestMapping("/getDesignLogicByKnowledgeBaseKey")
    public Result getDesignLogicByKnowledgeBaseKey(@RequestBody String data) {
        return taskCenterService.getDesignLogicByKnowledgeBaseKey(data);
    }

    @RequestMapping("/uploadDeviceExcel")
    public Result uploadDeviceExcel(HttpServletRequest req) {
        try {
            String userId = UserHeaderHolder.getUserId();
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            // 获取其他参数
            //String project_id = req.getParameter("projectId");
            //String project_node_id = req.getParameter("projectNodeId");

            MultipartFile file = mRequest.getFile("file");
            String fileName = file.getOriginalFilename();
            //获取文件名
            String fileExtend = fileName.substring(fileName.lastIndexOf(".") + 1);

            //判断只能上传xlsx和xlsm的文件
            if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {

                List<Map<String, String>> excelData = new ArrayList<>();
                List<Map<String, String>> processedList = ExcelUtils.parseExcel(file,0,0,0);

                if (processedList != null && processedList.size() > 0) {
                    String columnName1 = "器件封装";
                    String columnName2 = "装联方式";
                    String columnName3 = "器件大类";
                    String columnName4 = "器件小类";
                    String columnName5 = "设计阶段";
                    String columnName6 = "级别";
                    String columnName7 = "工艺知识checklist";
                    String columnName8 = "检查方法";
                    String columnName9 = "规则来源";
                    String columnName10 = "维护人员";

                    for (Map<String, String> row : processedList)
                    {
                        Map<String, String> tempMap=new HashMap<>();

                        String column1_value= row.get(columnName1);
                        String column2_value= row.get(columnName2);
                        String column3_value= row.get(columnName3);
                        String column4_value= row.get(columnName4);
                        String column5_value= row.get(columnName5);
                        String column6_value= row.get(columnName6);
                        String column7_value= row.get(columnName7);
                        String column8_value= row.get(columnName8);
                        String column9_value= row.get(columnName9);
                        String column10_value= row.get(columnName10);

                        tempMap.put(columnName1,column1_value);
                        tempMap.put(columnName2,column2_value);
                        tempMap.put(columnName3,column3_value);
                        tempMap.put(columnName4,column4_value);
                        tempMap.put(columnName5,column5_value);
                        tempMap.put(columnName6,column6_value);
                        tempMap.put(columnName7,column7_value);
                        tempMap.put(columnName8,column8_value);
                        tempMap.put(columnName9,column9_value);
                        tempMap.put(columnName10,column10_value);
                        excelData.add(tempMap);
                    }
                    return ResultUtil.success(processedList);
                } else {
                    return ResultUtil.error(500, "模板中没有有效数据,请检查", "", null);
                }
            } else {
                return ResultUtil.error(500, "只能上传xlsx、xls、xlsm的文件", "", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @RequestMapping("/uploadDesignExcel")
    public Result uploadDesignExcel(HttpServletRequest req) {
        try {
            String userId = UserHeaderHolder.getUserId();
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            // 获取其他参数
            //String project_id = req.getParameter("projectId");
            //String project_node_id = req.getParameter("projectNodeId");

            MultipartFile file = mRequest.getFile("file");
            String fileName = file.getOriginalFilename();
            //获取文件名
            String fileExtend = fileName.substring(fileName.lastIndexOf(".") + 1);

            //判断只能上传xlsx和xlsm的文件
            if (fileExtend.equals("xlsx") || fileExtend.equals("xls")) {

                List<Map<String, String>> excelData = new ArrayList<>();
                List<Map<String, String>> processedList = ExcelUtils.parseExcel(file,0,0,0);

                if (processedList != null && processedList.size() > 0) {
                    String columnName1 = "器件封装";
                    String columnName2 = "装联方式";
                    String columnName3 = "器件大类";
                    String columnName4 = "器件小类";
                    String columnName5 = "设计阶段";
                    String columnName6 = "级别";
                    String columnName7 = "工艺知识checklist";
                    String columnName8 = "检查方法";
                    String columnName9 = "规则来源";
                    String columnName10 = "维护人员";

                    for (Map<String, String> row : processedList)
                    {
                        Map<String, String> tempMap=new HashMap<>();

                        String column1_value= row.get(columnName1);
                        String column2_value= row.get(columnName2);
                        String column3_value= row.get(columnName3);
                        String column4_value= row.get(columnName4);
                        String column5_value= row.get(columnName5);
                        String column6_value= row.get(columnName6);
                        String column7_value= row.get(columnName7);
                        String column8_value= row.get(columnName8);
                        String column9_value= row.get(columnName9);
                        String column10_value= row.get(columnName10);

                        tempMap.put(columnName1,column1_value);
                        tempMap.put(columnName2,column2_value);
                        tempMap.put(columnName3,column3_value);
                        tempMap.put(columnName4,column4_value);
                        tempMap.put(columnName5,column5_value);
                        tempMap.put(columnName6,column6_value);
                        tempMap.put(columnName7,column7_value);
                        tempMap.put(columnName8,column8_value);
                        tempMap.put(columnName9,column9_value);
                        tempMap.put(columnName10,column10_value);
                        excelData.add(tempMap);
                    }
                    return ResultUtil.success(processedList);
                } else {
                    return ResultUtil.error(500, "模板中没有有效数据,请检查", "", null);
                }
            } else {
                return ResultUtil.error(500, "只能上传xlsx、xls、xlsm的文件", "", null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @RequestMapping("/uploadKnowledgeBaseData")
    public Result uploadKnowledgeBaseData(HttpServletRequest req) {
        try {
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) req;
            MultipartFile file = mRequest.getFile("file");
            String type = req.getParameter("type");

            return taskCenterService.uploadKnowledgeBaseData(file,type);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }




}
